package com.data.center.util;

import cn.hutool.core.util.StrUtil;
import com.data.center.dictionary.AdminDivisionLevel;
import com.data.center.dto.AdminDivisionDto;
import com.data.center.dto.RegionDivisionRelationDto;
import com.data.center.exception.exception.BizException;
import com.data.center.exception.info.CommonEnum;
import java.lang.reflect.Method;

/*
* 区域编码工具类
*
* */
public class AdminDivisionUtils {

    private static Method getFatherMethod;
    private static Class getFatherMethodClass;
    private static Object getFatherMethodEntity;

    public AdminDivisionUtils(Class classZ, Object entry, Method method) {

        AdminDivisionUtils.getFatherMethodEntity = entry;
        AdminDivisionUtils.getFatherMethod = method;
        AdminDivisionUtils.getFatherMethodClass = classZ;
    }

    public AdminDivisionDto parseToAdminDivsionDto(String code, String name) {
        AdminDivisionDto adminDivisionDto = new AdminDivisionDto();
        //Code	编码类（8）	区域（2位）+国标行政区划（6位）。
        //Name	文本类（50）	扩充国标，增加区域名称（东部、中部、西部、东北、港澳台）。
        //Level	编码类（2）	大区0，省1，市2，县3
        //Parent	编码类（8）	关联代码。
        //Status	枚举类	生效中、已失效。
        //Effective Date	时间日期类	yyyy-mm-dd
        //Expiry Date	时间日期类	yyyy-mm-dd

        name.replace(" ", "");

        return adminDivisionDto;
    }

    /*
        检查编码长度是否为6位
    */
    public static boolean checkCodeLengthIsSix(String code) {
        if(StrUtil.isEmpty(code)) {
            return false;
        }
        if (code.length() != 6) {
            return false;
        }
        return true;
    }

    /*
        检查编码长度是否为8位
    */
    public static boolean checkCodeLengthIsEight(String code) {
        if (StrUtil.isEmpty(code)) {
            return false;
        }
        if (code.length() != 8) {
            return false;
        }
        return true;
    }

    /*
    * 通用区域编码解析工具方法，可解析6或8位的编码
    * */
    public static AdminDivisionLevel getCodeLevel(String code) {
        if (code.length() == 6) {
            return getDivisionCodeLevel(code);
        } else if (code.length() == 8) {
            return getAreaCodeLevel(code);
        } else {
            throw new BizException(CommonEnum.DIVISION_CODE_WRONG);
        }
    }

    /*
    * 获取行政区域编码的等级，该方法仅用于对新输入的国标编码进行分析，仅能获取到省市区三级
    *
    * */
    public static AdminDivisionLevel getDivisionCodeLevel(String code) {
        if(!checkCodeLengthIsSix(code)) {
            throw new BizException(CommonEnum.CODE_SIZE_NOT_SIX);
        }

        int intCode = Integer.parseInt(code);
        int lastFourDigits = intCode % 10000;
        int lastTwoDigits = intCode % 100;

        if (lastFourDigits == 0) {
            return AdminDivisionLevel.PROVINCE;
        } else if (lastTwoDigits == 0) {
            return AdminDivisionLevel.CITY;
        } else {
            return AdminDivisionLevel.COUNTY;
        }

    }

    /*
     * 获取区域编码的等级，可解析8位编码，获取0-3四级
     *
     * */
    public static AdminDivisionLevel getAreaCodeLevel(String code) {
        if (!checkCodeLengthIsEight(code)) {
            throw new BizException(CommonEnum.CODE_SIZE_NOT_SIX);
        }

        int intCode = Integer.parseInt(code);
        int lastSixDigits = intCode % 1000000;
        int lastFourDigits = intCode % 10000;
        int lastTwoDigits = intCode % 100;

        if (lastSixDigits == 0) {
            return AdminDivisionLevel.REGION;
        } else if (lastFourDigits == 0) {
            return AdminDivisionLevel.PROVINCE;
        } else if (lastTwoDigits == 0) {
            return AdminDivisionLevel.CITY;
        } else {
            return AdminDivisionLevel.COUNTY;
        }
    }

    /*
     * 获取区域编码的父编码，可以解析6或8位
     *
     * */
    public static String getFatherCode(String code) {
        if (checkCodeLengthIsEight(code)) {
            AdminDivisionLevel level = getAreaCodeLevel(code);
            // 根据等级选择其父编码
            switch (level) {
                case REGION:
                    return "00000000";
                case PROVINCE:
                    String divisionCode = code.substring(2);
                    return getDivisionFatherCode(divisionCode);
                case CITY:
                    return code.substring(0, 4) + "0000";
                case COUNTY:
                    return code.substring(0, 6) + "00";
                default:
                    throw new BizException(CommonEnum.DIVISION_CODE_WRONG);
            }
        } else if (checkCodeLengthIsSix(code)) {
            AdminDivisionLevel level = getDivisionCodeLevel(code);
            // 根据等级选择其父编码
            switch (level) {
                case PROVINCE:
                    return getDivisionFatherCode(code);
                case CITY:
                    String provinceCode = code.substring(0, 2) + "0000";
                    return getDivisionFatherCode(provinceCode).substring(0, 2) + provinceCode;
                case COUNTY:
                    String cityCode = code.substring(0, 4) + "00";
                    return getDivisionFatherCode(cityCode).substring(0, 2) + code.substring(0, 4) + "00";
                default:
                    throw new BizException(CommonEnum.DIVISION_CODE_WRONG);
            }
        } else {
            throw new BizException(CommonEnum.DIVISION_CODE_WRONG);
        }
    }

    /*
     * 获取6位行政区域编码的父大区编码，
     *
     * */
    public static String getDivisionFatherCode(String code) {
        if (!checkCodeLengthIsSix(code)) {
            throw new BizException(CommonEnum.CODE_SIZE_NOT_SIX);
        }

        String provinceCode = code.substring(0, 2) + "0000";
        String fatherCode;
        try {
            RegionDivisionRelationDto dto = (RegionDivisionRelationDto) getFatherMethod.invoke(getFatherMethodEntity, provinceCode);
            if (dto != null) {
                fatherCode = dto.getRegionCode();
            } else {
                throw new BizException(CommonEnum.FATHER_CODE_CAN_NOT_FIND);
            }
        } catch (Exception e) {
            throw new BizException(e.toString());
        }

        return fatherCode;
    }

}
